package toolx

import (
	"bufio"
	"os"
	"strings"
	"unicode"

	"gitee.com/workits/pkgs/utilx"
	"github.com/flytam/filenamify"
	"golang.org/x/text/cases"
	"golang.org/x/text/language"
)

// ModGlobalConfig 修改global.go
func ModGlobalConfig(projDir, comp string) {
	switch comp {
	case "http":
		lines := ReadFileByLine(projDir + PS + "internal" + PS + "config" + PS + "global.go")
		newLines := make([]string, 0)
		for _, line := range lines {
			newLine := strings.Trim(strings.TrimSpace(line), "\t")
			if newLine == "ServerConfig" || newLine == "JwtConfig" || newLine == "CasbinConfig" || newLine == "CaptchaConfig" {
				panic(ErrExist)
			}
			if newLine != "}" {
				newLines = append(newLines, line)
			} else {
				newLines = append(newLines, "\tServerConfig")
				newLines = append(newLines, "\tJwtConfig")
				newLines = append(newLines, "\tCasbinConfig")
				newLines = append(newLines, "\tCaptchaConfig")
				newLines = append(newLines, "}")
			}
		}
		if err := utilx.CreateFile(projDir+PS+"internal"+PS+"config"+PS+"global.go", []byte(strings.Join(newLines, "\n"))); err != nil {
			panic(err)
		}
	case "rpc":
	case "schedule":
	}
}

// RollbackGlobalConfig 回滚global.go
func RollbackGlobalConfig(projDir, comp string) {
	switch comp {
	case "http":
		lines := ReadFileByLine(projDir + PS + "internal" + PS + "config" + PS + "global.go")
		newLines := make([]string, 0)
		for _, line := range lines {
			newLine := strings.Trim(strings.TrimSpace(line), "\t")
			if newLine == "ServerConfig" || newLine == "JwtConfig" || newLine == "CasbinConfig" {
				continue
			}
			newLines = append(newLines, line)
		}
		if err := utilx.CreateFile(projDir+PS+"internal"+PS+"config"+PS+"global.go", []byte(strings.Join(newLines, "\n"))); err != nil {
			panic(err)
		}
	case "rpc":
	case "schedule":
	}
}

// RollbackGomod 回滚go.mod
func RollbackGomod(projDir, comp string) {
	switch comp {
	case "http":
		lines := ReadFileByLine(projDir + PS + "internal" + PS + "config" + PS + "global.go")
		newLines := make([]string, 0)
		for _, line := range lines {
			newLine := strings.Trim(strings.TrimSpace(line), "\t")
			if strings.Contains(newLine, "github.com/gin-gonic/gin") {
				continue
			}
			newLines = append(newLines, line)
		}
		if err := utilx.CreateFile(projDir+PS+"internal"+PS+"config"+PS+"global.go", []byte(strings.Join(newLines, "\n"))); err != nil {
			panic(err)
		}
	case "rpc":
	case "schedule":
	}
}

// ReadFileByLine 读取文件
func ReadFileByLine(filePath string) []string {
	f, err := os.Open(filePath)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// 逐行读取
	s := bufio.NewScanner(f)
	lines := make([]string, 0)
	for s.Scan() {
		lines = append(lines, s.Text())
	}
	if s.Err() != nil {
		panic(err)
	}

	return lines
}

// AppendFile 在文件末尾追加内容
func AppendFile(filePath, content string) {
	f, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	if _, err := f.WriteString(content + "\n"); err != nil {
		panic(err)
	}
}

// UderscoreToUpperCamelCase 下划线单词转为大写驼峰单词
func UderscoreToUpperCamelCase(s string) string {
	s = strings.Replace(s, "_", " ", -1)
	s = cases.Title(language.Und, cases.NoLower).String(s)
	return strings.Replace(s, " ", "", -1)
}

// UderscoreToLowerCamelCase 下划线单词转为小写驼峰单词
func UderscoreToLowerCamelCase(s string) string {
	s = UderscoreToUpperCamelCase(s)
	return string(unicode.ToLower(rune(s[0]))) + s[1:]
}

// CamelCaseToUdnderscore 驼峰单词转下划线单词
func CamelCaseToUdnderscore(s string) string {
	var output []rune
	for i, r := range s {
		if i == 0 {
			output = append(output, unicode.ToLower(r))
		} else {
			if unicode.IsUpper(r) {
				output = append(output, '_')
			}

			output = append(output, unicode.ToLower(r))
		}
	}
	return string(output)
}

// IsFolderName 是否是文件夹名称
func IsFolderName(name string) bool {
	newName, err := filenamify.Filenamify(name, filenamify.Options{})
	if err != nil {
		return false
	}
	return name == newName
}
